use rusqlite::{params, Connection, Result};use super::models::Notice;

/// 分页查询参数结构体
#[derive(Debug)]
pub struct PaginationParams {
    /// 当前页码，从1开始
    pub page: i64,
    /// 每页记录数
    pub page_size: i64,
}

/// 分页查询结果结构体
#[derive(Debug)]
pub struct PaginationResult<T> {
    /// 查询结果数据
    pub data: Vec<T>,
    /// 总记录数
    pub total_count: i64,
    /// 总页数
    pub total_pages: i64,
    /// 当前页码
    pub current_page: i64,
    /// 每页记录数
    pub page_size: i64,
}

/// 查询数据库模块
/// 
/// 提供数据库查询功能，主要包括分页查询公告信息等操作。

/**
 * 分页查询公告信息
 * 
 * 从notice_table表中分页查询公告信息，支持页码和每页记录数设置
 * 
 * @param conn 数据库连接
 * @param params 分页查询参数
 * @return 成功时返回PaginationResult<Notice>对象，失败时返回错误
 */
fn get_notices_with_pagination(
    conn: &Connection,
    params: &PaginationParams
) -> Result<PaginationResult<Notice>> {
    // 计算偏移量
    let offset = (params.page - 1) * params.page_size;
    
    // 查询总记录数
    let total_count: i64 = conn.query_row(
        "SELECT COUNT(*) FROM notice_table",
        [],
        |row| row.get(0)
    )?;
    
    // 计算总页数
    let total_pages = if total_count == 0 {
        0
    } else {
        (total_count + params.page_size - 1) / params.page_size
    };
    
    // 分页查询公告信息
    let mut stmt = conn.prepare(
        "SELECT notice_id, notice_date, area, identifier, notice_name 
         FROM notice_table 
         ORDER BY notice_date DESC 
         LIMIT ? OFFSET ?"
    )?;
    
    let notices = stmt.query_map(
        params![params.page_size, offset],
        |row| {
            Ok(Notice {
                notice_id: row.get(0)?,
                notice_date: row.get(1)?,
                area: row.get(2)?,
                identifier: row.get(3)?,
                notice_name: row.get(4)?,
            })
        }
    )?;
    
    // 收集查询结果
    let mut data = Vec::new();
    for notice in notices {
        data.push(notice?);
    }
    
    // 构建并返回分页结果
    Ok(PaginationResult {
        data,
        total_count,
        total_pages,
        current_page: params.page,
        page_size: params.page_size,
    })
}

/**
 * 按照区域筛选分页查询公告信息
 * 
 * 根据指定区域筛选公告，并支持分页查询
 * 
 * @param conn 数据库连接
 * @param params 分页查询参数
 * @param area 区域筛选条件
 * @return 成功时返回PaginationResult<Notice>对象，失败时返回错误
 */
fn get_notices_by_area(
    conn: &Connection,
    params: &PaginationParams,
    area: &str
) -> Result<PaginationResult<Notice>> {
    // 计算偏移量
    let offset = (params.page - 1) * params.page_size;
    
    // 查询符合条件的总记录数
    let total_count: i64 = conn.query_row(
        "SELECT COUNT(*) FROM notice_table WHERE area = ?",
        params![area],
        |row| row.get(0)
    )?;
    
    // 计算总页数
    let total_pages = if total_count == 0 {
        0
    } else {
        (total_count + params.page_size - 1) / params.page_size
    };
    
    // 分页查询符合条件的公告信息
    let mut stmt = conn.prepare(
        "SELECT notice_id, notice_date, area, identifier, notice_name 
         FROM notice_table 
         WHERE area = ? 
         ORDER BY notice_date DESC 
         LIMIT ? OFFSET ?"
    )?;
    
    let notices = stmt.query_map(
        params![area, params.page_size, offset],
        |row| {
            Ok(Notice {
                notice_id: row.get(0)?,
                notice_date: row.get(1)?,
                area: row.get(2)?,
                identifier: row.get(3)?,
                notice_name: row.get(4)?,
            })
        }
    )?;
    
    // 收集查询结果
    let mut data = Vec::new();
    for notice in notices {
        data.push(notice?);
    }
    
    // 构建并返回分页结果
    Ok(PaginationResult {
        data,
        total_count,
        total_pages,
        current_page: params.page,
        page_size: params.page_size,
    })
}

/**
 * 整合的公告查询函数，支持按区域筛选或获取全部数据
 * 
 * 如果area参数为"全部"，则获取所有公告数据；否则按指定区域筛选
 * 
 * @param conn 数据库连接
 * @param params 分页查询参数
 * @param area 区域筛选条件，传入"全部"时获取所有数据
 * @return 成功时返回PaginationResult<Notice>对象，失败时返回错误
 */
pub fn get_notices_by_area_or_all(
    conn: &Connection,
    params: &PaginationParams,
    area: &str
) -> Result<PaginationResult<Notice>> {
    // 如果area为空字符串，则调用获取所有数据的函数
    if area.is_empty() {
        get_notices_with_pagination(conn, params)
    } else {
        // 否则按指定区域筛选
        get_notices_by_area(conn, params, area)
    }
}

/**
 * 获取所有区县名称
 * 
 * 从canton_table表中获取所有区县的名称
 * 
 * @param conn 数据库连接
 * @return 成功时返回区县名称列表，失败时返回错误
 */
pub fn get_all_cantons(
    conn: &Connection
) -> Result<Vec<String>> {
    // 查询canton_table表中的所有区县名称
    let mut stmt = conn.prepare(
        "SELECT canton_name FROM canton_table ORDER BY id"
    )?;
    
    let canton_iter = stmt.query_map([], |row| row.get(0))?;
    
    // 收集查询结果
    let mut cantons = Vec::new();
    for canton in canton_iter {
        cantons.push(canton?);
    }
    
    Ok(cantons)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::db::sqlite::create_db;
    
    #[test]
    fn test_get_notices_with_pagination() {
        // 创建数据库连接
        let conn = create_db().unwrap();
        
        // 创建分页参数（每页20条）
        let params = PaginationParams {
            page: 1,
            page_size: 20,
        };
        
        // 执行分页查询
        let result = get_notices_with_pagination(&conn, &params).unwrap();
        
        // 打印查询结果信息
        println!("总记录数: {}", result.total_count);
        println!("总页数: {}", result.total_pages);
        println!("当前页数据条数: {}", result.data.len());
        
        // 验证查询结果的合理性
        assert!(result.data.len() <= params.page_size as usize);
        assert!(result.total_pages >= 0);
    }
}